﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Xml;
using System.Xml.Linq;
using System.Text;
using System.Windows.Forms;
using System.Diagnostics;
using System.IO;
using ConsoleRedirection;



namespace KentekenHerkenning
{
    public partial class LicencePlateForm : Form
    {
        /// <summary>
        /// Localisation implemented by: Alexander Streng
        /// Lighting implemented by: Pascal Schotman
        /// Rotation implemented by: Marleen Schilt, deleted due to bad results
        /// OCR implemented by: Dylan Snel
        /// </summary>
        TextWriter _writer = null;
        private String workingDirectory = "";
        private XMLProvider imageXmlInput;
       // private XMLProvider testResultXml;
        List<Double> ocrAccuracy = new List<Double>();
        List<long> executionTime = new List<long>();
        BackgroundWorker BW = new BackgroundWorker();
        Stopwatch sw = new Stopwatch();
        int perfectImages;
        private List<TestsetImage> imagesToProcess = new List<TestsetImage>();


        public LicencePlateForm()
        {
            InitializeComponent();
            BW.WorkerReportsProgress = true;
            openXMLDialog.Filter = "XML files (.xml)|*.xml";
            BW.ProgressChanged += new ProgressChangedEventHandler(BW_ProgressChanged);
            BW.RunWorkerCompleted += new RunWorkerCompletedEventHandler(BW_RunWorkerCompleted);
            BW.DoWork += new DoWorkEventHandler(BW_DoWork);
        }

        void BW_DoWork(object sender, DoWorkEventArgs e)
        {
            int[] stats = new int[2];

            List<Result> RL = new List<Result>();
            try
            {
                for (int i = 0; i < imagesToProcess.Count; i++)
                {
                    BW.ReportProgress((100 / imagesToProcess.Count) * (i + 1), imagesToProcess[i].fileName + "+" + (i + 1));
                    RL.Add((Result)LicensePlateRecognition.processImage(imagesToProcess[i]));
                }
            }
            catch (Exception processImageExeptione)
            {
                Console.WriteLine("html format exception : " + processImageExeptione);
            }
            try
            {
                HTMLformatter HF = new HTMLformatter();
                HF.Format(RL);
            }
            catch (Exception htmlFormatExceptione)
            {
                Console.WriteLine("html format exception : " + htmlFormatExceptione);
            }

            try
            {
                XMLoutput.saveOutPut(RL);
            }
            catch (Exception XMLException)
            {
                Console.WriteLine("XML exception : " +XMLException);
            }
        }

        void BW_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            sw.Stop();
            if ((e.Cancelled == true))
            {
                Console.WriteLine("Backgroundworker was canceled for some reason.");
            }

            else if (!(e.Error == null))
            {
                Console.WriteLine("Backgroundworker report an error.");
                Console.WriteLine(e.Error.Message);
            }

            else
            {
               Console.WriteLine("Backgroundworker done succesfully");
               TimeLabel.Text = "Time elapsed: " + sw.ElapsedMilliseconds + " ms";
               progressBar2.Value = 100;
            }
        }

        void BW_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            progressBar2.Value = e.ProgressPercentage;
            string[] s = e.UserState.ToString().Split('+');
            CountLabel.Text = "Count: " + s[1] + "/" + imagesToProcess.Count;
            FileLabel.Text = "File: " + s[0];
            TimeLabel.Text = "Time elapsed: " + sw.ElapsedMilliseconds + " ms";


        }

        private void openToolStripMenuItem1_Click(object sender, EventArgs e)
        {
            OpenFileDialog openFileDialog = new OpenFileDialog();
            openFileDialog.InitialDirectory = "Pictures\\";
            openFileDialog.FileName = "";
            if (openFileDialog.ShowDialog(this) == DialogResult.OK)
            {
                String filename = openFileDialog.FileName;
                Console.Write("Picture has been opened\n");
            }
        }

        private void srcPictureBox_DoubleClick(object sender, EventArgs e)
        {
            OpenFileDialog openFileDialog = new OpenFileDialog();
            openFileDialog.InitialDirectory = "Pictures\\";
            openFileDialog.FileName = "";
            if (openFileDialog.ShowDialog(this) == DialogResult.OK)
            {
                String filename = openFileDialog.FileName;
            }
        } 

        private void Form1_Load(object sender, EventArgs e)
        {
            // Instantiate the writer
            _writer = new TextBoxStreamWriter(consoleTextBox);

            // Redirect the out Console stream
            Console.SetOut(_writer);

            Console.WriteLine("Welcome to the Licence Plate Recognition Program!");
        }

        private void recognisePlateToolStripMenuItem_Click(object sender, EventArgs e)
        {
            sw.Reset();
            Console.WriteLine("Licenseplate recognition has been started");

            imagesToProcess.Clear();

            openXmlAndLoadImages();

            

           // srcPictureBox.Image = ((Bitmap)imagesToProcess[0].SourceImage);
            Console.WriteLine("Starting the Backgroundworker");
            sw.Start();
            if (BW.IsBusy != true)
            {
                BW.RunWorkerAsync();
            }


            //output here
        }

        private void openXmlAndLoadImages()
        {

            if (openXMLDialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                Point upperleft = new Point(), upperright = new Point(), lowerleft = new Point(), lowerright = new Point();
                imageXmlInput = new XMLProvider(new FileInfo(openXMLDialog.FileName));
                FileInfo fi = new FileInfo(openXMLDialog.FileName);
                workingDirectory = fi.Directory.ToString();
                if (imageXmlInput.rootNode.Name == "testsamples")
                {

                    foreach (XmlNode imgNode in imageXmlInput.rootNode.ChildNodes)
                    {
                        List<String> licensePlates = new List<String>();

                        foreach (XmlNode potentialLicensePlateNode in imgNode.ChildNodes)
                            if (potentialLicensePlateNode.Name == "license_plate")
                            {
                                foreach (XmlNode potentialTextNode in potentialLicensePlateNode.ChildNodes)
                                    if (potentialTextNode.Name == "text")
                                    {
                                        licensePlates.Add(potentialTextNode.InnerText);
                                    }
                                    else if (potentialTextNode.Name == "location")
                                    {
                                        upperleft = new Point(Convert.ToInt32(potentialTextNode.ChildNodes[0].Attributes["x"].Value), Convert.ToInt32(potentialTextNode.ChildNodes[0].Attributes["y"].Value));
                                        upperright = new Point(Convert.ToInt32(potentialTextNode.ChildNodes[1].Attributes["x"].Value), Convert.ToInt32(potentialTextNode.ChildNodes[1].Attributes["y"].Value));
                                        lowerleft = new Point(Convert.ToInt32(potentialTextNode.ChildNodes[2].Attributes["x"].Value), Convert.ToInt32(potentialTextNode.ChildNodes[2].Attributes["y"].Value));
                                        lowerright = new Point(Convert.ToInt32(potentialTextNode.ChildNodes[3].Attributes["x"].Value), Convert.ToInt32(potentialTextNode.ChildNodes[3].Attributes["y"].Value));

                                    }
                            };

                        String[] originalLicensePlates = licensePlates.ToArray();

                        try
                        {
                            TestsetImage tsi = new TestsetImage(new Bitmap(workingDirectory + "\\" + imgNode.Attributes["filename"].Value), imgNode.Attributes["filename"].Value, licensePlates.ToArray());
                            tsi.upperleft = upperleft;
                            tsi.upperright = upperright;
                            tsi.lowerleft = lowerleft;
                            tsi.lowerright = lowerright;



                            imagesToProcess.Add(tsi);
                        }
                        catch
                        {
                            Console.WriteLine("Kon image: " + workingDirectory + "\\" + imgNode.Attributes["filename"].Value + " niet loaden");
                        }
                    }
                }
            }
        }


        private void srcPictureBox_Click(object sender, EventArgs e)
        {

        }

        private void showResultsToolStripMenuItem_Click(object sender, EventArgs e)
        {
            ResultViewer RV = new ResultViewer(System.Reflection.Assembly.GetExecutingAssembly().Location.Replace("FinalKentekenHerkenning.exe", "") + "Results.html");
            RV.Show();
        }
    }
}
